﻿using System;
using System.ComponentModel.Design;
using System.Runtime.InteropServices;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using AntEater.ComponentModel;
using AntEater.Integration.Attributes;
using AntEater.Integration.Editors;
using AntEater.Integration.OptionPages;
using AntEater.Integration.ToolWindows;
using AntEater.Runtime;

namespace AntEater.Integration
{
    /// <summary>
    /// Provides the Package for the Visual Studio Integration.
    /// </summary>
    // General Package definitions
    [PackageRegistration(UseManagedResourcesOnly = true)]
    [DefaultRegistryRoot(Strings.RegistryRoot)]
    [InstalledProductRegistration(true, null, null, null)]
    [ProvideLoadKey(Strings.MinimumEdition, Strings.VersionNumber, Strings.ApplicationName, Strings.CompanyName, Ressources.PackageLoadKey)]

    // Provide AutoLoad for automatic loading of the package on Visual Studio startup
    [ProvideAutoLoad(UIContextGuids80.NoSolution)]

    // Provide the "General" options page
    [ProvideOptionPage(typeof(GeneralOptionPage), Strings.ApplicationName, Strings.GeneralOptionName, Ressources.ApplicationName, Ressources.GeneralOptionName, true, SupportsProfiles = true)]
    [ProvideProfile(typeof(GeneralOptionPage), Strings.ApplicationName, Strings.GeneralOptionName, Ressources.ApplicationName, Ressources.GeneralOptionName, true, DescriptionResourceID = Ressources.GeneralOptionDescription)]

    // Provide the "External Build Properties" options page
    [ProvideOptionPage(typeof(ExternalBuildPropertiesOptionPage), Strings.ApplicationName, Strings.ExternalBuildPropertiesOptionName, Ressources.ApplicationName, Ressources.ExternalBuildPropertiesOptionName, true, SupportsProfiles = true)]
    [ProvideProfile(typeof(ExternalBuildPropertiesOptionPage), Strings.ApplicationName, Strings.ExternalBuildPropertiesOptionName, Ressources.ApplicationName, Ressources.ExternalBuildPropertiesOptionName, true, DescriptionResourceID = Ressources.ExternalBuildPropertiesOptionDescription)]

    // Provide the Solution Properties Section
    [ProvideSolutionPersistence(Guids.PackageId, Strings.ApplicationName)]

    // Provide the menus
    [ProvideMenuResource(Ressources.Package, 1)]

    // Provide the "Target Execution" tool window
    [ProvideToolWindow(typeof(TargetExecutionToolWindow), Transient = false, MultiInstances = false, Style = VsDockStyle.Tabbed, Orientation = ToolWindowOrientation.Right, Window = ToolWindowGuids80.PropertiesWindow)]
    [ProvideToolWindowVisibility(typeof(TargetExecutionToolWindow), UIContextGuids80.SolutionExistsAndNotBuildingAndNotDebugging)]

    // Provide the "Build File" Editor
    [ProvideEditorFactory(typeof(BuildFileEditorFactory), Ressources.BuildFileEditorName, TrustLevel = __VSEDITORTRUSTLEVEL.ETL_AlwaysTrusted)]
    [ProvideEditorLogicalView(typeof(BuildFileEditorFactory), LogicalViewID.Designer, IsTrusted = true)]
    [ProvideEditorXmlDesignerView(typeof(BuildFileEditorFactory), LogicalViewID.Designer, Name = Strings.BuildFileEditorName, XmlNamespace = Strings.BuildFileEditorXmlNamespace, MatchBoth = false)]
    
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorBuildExtension, 100, ProjectGuid = Guids.ProjectCSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorBuildExtension, 100, ProjectGuid = Guids.ProjectVisualBasicId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorBuildExtension, 100, ProjectGuid = Guids.ProjectJSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorBuildExtension, 100, ProjectGuid = Guids.ProjectMiscellaneousFilesId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorBuildExtension, 100, ProjectGuid = Guids.ProjectSolutionFolderId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]

    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorTargetsExtension, 100, ProjectGuid = Guids.ProjectCSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorTargetsExtension, 100, ProjectGuid = Guids.ProjectVisualBasicId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorTargetsExtension, 100, ProjectGuid = Guids.ProjectJSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorTargetsExtension, 100, ProjectGuid = Guids.ProjectMiscellaneousFilesId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorTargetsExtension, 100, ProjectGuid = Guids.ProjectSolutionFolderId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]

    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorCSharpExtension, 100, ProjectGuid = Guids.ProjectCSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorCSharpExtension, 100, ProjectGuid = Guids.ProjectVisualBasicId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorCSharpExtension, 100, ProjectGuid = Guids.ProjectJSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorCSharpExtension, 100, ProjectGuid = Guids.ProjectMiscellaneousFilesId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorCSharpExtension, 100, ProjectGuid = Guids.ProjectSolutionFolderId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]

    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorVisualBasicExtension, 100, ProjectGuid = Guids.ProjectCSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorVisualBasicExtension, 100, ProjectGuid = Guids.ProjectVisualBasicId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorVisualBasicExtension, 100, ProjectGuid = Guids.ProjectJSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorVisualBasicExtension, 100, ProjectGuid = Guids.ProjectMiscellaneousFilesId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorVisualBasicExtension, 100, ProjectGuid = Guids.ProjectSolutionFolderId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]

    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorJSharpExtension, 100, ProjectGuid = Guids.ProjectCSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorJSharpExtension, 100, ProjectGuid = Guids.ProjectVisualBasicId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorJSharpExtension, 100, ProjectGuid = Guids.ProjectJSharpId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorJSharpExtension, 100, ProjectGuid = Guids.ProjectMiscellaneousFilesId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]
    [ProvideEditorExtension(typeof(BuildFileEditorFactory), Strings.BuildFileEditorJSharpExtension, 100, ProjectGuid = Guids.ProjectSolutionFolderId, TemplateDir = Strings.BuildFileEditorTemplateDirectory, NameResourceID = Ressources.ApplicationName)]

    // Set GUID of the package
    [Guid(Guids.PackageId)]
    [CLSCompliant(false)]
    public sealed class VisualStudioPackage : Package, IVsInstalledProduct, IVsPersistSolutionProps, IDisposable
    {
        private IAntEaterRuntime _runtime;
        private SolutionManager _solutionManager;
        private BuildFileEditorFactory _buildFileEditorFactory;
        private IVsOutputWindowPane _outputPane;

        private bool _projectHasChanged;

        /// <summary>
        /// Initializes this instance.
        /// </summary>
        protected override void Initialize() {

            // Initialize the base package            
            base.Initialize();

            // Get the runtime instance
            _runtime = AntEaterRuntime.Instance;
            _runtime.Solution.Project.Changed += new EventHandler<EventArgs>(this.ProjectChanged);

            // Create the output pane and register to the output event of the runtime instance
            _outputPane = base.GetOutputPane(Guids.OutputWindowIdGuid, Strings.OutputWindowName);
            _runtime.Output.LineWritten += new EventHandler<OutputEventArgs>(this.OutputLineWritten);
            _runtime.Output.Cleared += new EventHandler<EventArgs>(this.OutputCleared);


            // Read the options out of the registry
            this.InitializeOptions(_runtime.Options);

            // Initialize the command handlers of the package
            this.InitializeCommands();

            // Create the editor factory
            _buildFileEditorFactory = new BuildFileEditorFactory(this, _runtime);
            base.RegisterEditorFactory(_buildFileEditorFactory);


            // Initialize the solution manager
            SolutionManager.Initialize(this, _runtime);
            _solutionManager = SolutionManager.GetInstance();
        }

        /// <summary>
        /// Initializes the options.
        /// </summary>
        /// <param name="options">The options.</param>
        private void InitializeOptions(Options options) {

            // Read options and put them to the runtime instance
            GeneralOptionPage general = (GeneralOptionPage)this.GetDialogPage(typeof(GeneralOptionPage));
            options.BuildEnginePath = general.BuildEnginePath;
            options.BuildLoggingVerbosity = general.BuildLoggingVerbosity;
            options.ShowImportedTargets = general.ShowImportedTargets;
            options.BuildFileExtensions.Clear();
            options.BuildFileExtensions.AddRange(general.BuildFileExtensions);

            ExternalBuildPropertiesOptionPage externalBuildProperties = (ExternalBuildPropertiesOptionPage)this.GetDialogPage(typeof(ExternalBuildPropertiesOptionPage));
            options.ExternalBuildProperties.Clear();
            options.ExternalBuildProperties.AddRange(externalBuildProperties.ExternalBuildProperties);
        }

        /// <summary>
        /// Initializes the commands.
        /// </summary>
        private void InitializeCommands() {

            // Add "Target Execution Window" command
            Utilities.AddCommand(this, new EventHandler(ShowTargetExecutionWindow), Commands.ShowTargetExecutionWindowCommand);
        }

        /// <summary>
        /// Writes the line to output.
        /// </summary>
        /// <param name="line">The line.</param>
        private void WriteLineToOutput(string line) {

            // Write line to the output window and activate the output pane
            _outputPane.Activate();
            _outputPane.OutputString(line + Environment.NewLine);
        }

        /// <summary>
        /// Clears the output.
        /// </summary>
        private void ClearOutput() {

            // Clear the output window
            _outputPane.Clear();
        }

        /// <summary>
        /// Shows the tool window.
        /// </summary>
        /// <param name="toolWindowType">Type of the tool window.</param>
        private void ShowToolWindow(Type toolWindowType) {

            // Show the tool window
            ToolWindowPane toolWindow = this.FindToolWindow(toolWindowType, 0, true);
            if ((toolWindow != null) && (toolWindow.Frame != null)) {
                IVsWindowFrame windowFrame = (IVsWindowFrame)toolWindow.Frame;
                windowFrame.Show();
            }
        }

        /// <summary>
        /// Lines the written.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="AntEater.ComponentModel.OutputEventArgs"/> instance containing the event data.</param>
        private void OutputLineWritten(object sender, OutputEventArgs e) {
            this.WriteLineToOutput(e.Line);
        }

        /// <summary>
        /// Outputs the cleared.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void OutputCleared(object sender, EventArgs e) {
            this.ClearOutput();
        }

        /// <summary>
        /// Projects the changed.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ProjectChanged(object sender, EventArgs e) {
            _projectHasChanged = true;
        }

        /// <summary>
        /// Shows the target execution window.
        /// </summary>
        /// <param name="sender">The sender.</param>
        /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
        private void ShowTargetExecutionWindow(object sender, EventArgs e) {
            this.ShowToolWindow(typeof(TargetExecutionToolWindow));
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose() {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        /// <summary>
        /// Disposes the specified disposing.
        /// </summary>
        /// <param name="disposing">if set to <c>true</c> [disposing].</param>
        protected override void Dispose(bool disposing) {

            try {
                if (disposing) {
                    // Dispose editor factory
                    if (_buildFileEditorFactory != null) {
                        _buildFileEditorFactory.Dispose();
                        _buildFileEditorFactory = null;
                    }

                    // Dispose solution manager
                    if (_solutionManager != null) {
                        _solutionManager.Dispose();
                        _solutionManager = null;
                    }
                }

            } finally {
                base.Dispose(disposing);
            }
        }

        /// <summary>
        /// Reads the solution props.
        /// </summary>
        /// <param name="pHierarchy">The p hierarchy.</param>
        /// <param name="pszProjectName">Name of the PSZ project.</param>
        /// <param name="pszProjectMk">The PSZ project mk.</param>
        /// <param name="pszKey">The PSZ key.</param>
        /// <param name="fPreLoad">The f pre load.</param>
        /// <param name="pPropBag">The p prop bag.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.ReadSolutionProps(IVsHierarchy pHierarchy, string pszProjectName, string pszProjectMk, string pszKey, int fPreLoad, IPropertyBag pPropBag) {

            // Read properties of the solution
            if ((pHierarchy == null) && (pszKey == Strings.SettingsSection)) {

                // Get Project
                Solution solution = _runtime.Solution;
                Project project = _runtime.Solution.Project;

                // Get Build Files
                int counter = 0;
                bool error = false;
                while (error == false) {
                    try {
                        // Read build file from properties
                        string key = Strings.SettingsBuildFileKey + counter;
                        object value;
                        pPropBag.Read(key, out value, null, 0, null);

                        // Create new build file and add it to the project
                        if (solution.BuildFiles.Contains(value.ToString())) {
                            BuildFile buildFile = solution.BuildFiles[value.ToString()];
                            project.BuildFiles.Add(buildFile);

                            // Get External Build Properies of the Build File
                            int propertyCounter = 0;
                            bool propertyError = false;
                            while (propertyError == false) {

                                try {
                                    // Read External Build Property of the build file from the properties
                                    string propertyKey = key + Strings.SettingsExternalBuildPropertyKey + propertyCounter;
                                    object propertyValue;
                                    pPropBag.Read(propertyKey, out propertyValue, null, 0, null);

                                    // Parse External Build Property
                                    string[] propertyValues = propertyValue.ToString().Split(new string[] { ";" }, StringSplitOptions.None);

                                    if (propertyValues.Length >= 2) {
                                        // Create new external build property and add it to the project
                                        ExternalBuildProperty property = new ExternalBuildProperty(propertyValues[0], propertyValues[1]);
                                        buildFile.ExternalBuildProperties.Add(property);
                                    }

                                } catch (ArgumentException) {
                                    propertyError = true;
                                }

                                propertyCounter++;
                            }
                        }

                    } catch (ArgumentException) {
                        error = true;
                    }

                    counter++;
                }


                // Get External Build Properties
                counter = 0;
                error = false;
                while (error == false) {
                    try {
                        // Read External Build Property from the properties
                        string key = Strings.SettingsExternalBuildPropertyKey + counter;
                        object value;
                        pPropBag.Read(key, out value, null, 0, null);

                        // Parse External Build Property
                        string[] values = value.ToString().Split(new string[] { ";" }, StringSplitOptions.None);

                        if (values.Length >= 2) {
                            // Create new external build property and add it to the project
                            ExternalBuildProperty property = new ExternalBuildProperty(values[0], values[1]);
                            project.ExternalBuildProperties.Add(property);
                        }

                    } catch (ArgumentException) {
                        error = true;
                    }

                    counter++;
                }
            }

            // Reset changed status
            _projectHasChanged = false;

            return VSConstants.S_OK;
        }

        /// <summary>
        /// Queries the save solution props.
        /// </summary>
        /// <param name="pHierarchy">The p hierarchy.</param>
        /// <param name="pqsspSave">The PQSSP save.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.QuerySaveSolutionProps(IVsHierarchy pHierarchy, VSQUERYSAVESLNPROPS[] pqsspSave) {

            // Check if properties shoud be saved
            if (pHierarchy == null) {

                if (_projectHasChanged == true) {
                    pqsspSave[0] = VSQUERYSAVESLNPROPS.QSP_HasDirtyProps;
                } else {
                    pqsspSave[0] = VSQUERYSAVESLNPROPS.QSP_HasNoDirtyProps;
                }
            }
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Saves the solution props.
        /// </summary>
        /// <param name="pHierarchy">The p hierarchy.</param>
        /// <param name="pPersistence">The p persistence.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.SaveSolutionProps(IVsHierarchy pHierarchy, IVsSolutionPersistence pPersistence) {

            // Save properties for the solution
            if (pHierarchy == null) {
                pPersistence.SavePackageSolutionProps(VSConstants.S_OK, pHierarchy, this, Strings.SettingsSection);
            }

            return VSConstants.S_OK;
        }

        /// <summary>
        /// Writes the solution props.
        /// </summary>
        /// <param name="pHierarchy">The p hierarchy.</param>
        /// <param name="pszKey">The PSZ key.</param>
        /// <param name="pPropBag">The p prop bag.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.WriteSolutionProps(IVsHierarchy pHierarchy, string pszKey, IPropertyBag pPropBag) {

            if ((pHierarchy == null) && (pszKey == Strings.SettingsSection)) {

                // Write build files to the properties
                int counter = 0;
                foreach (BuildFile buildFile in _runtime.Solution.Project.BuildFiles) {
                    // Write value to the properties
                    string key = Strings.SettingsBuildFileKey + counter;
                    object value = buildFile.BuildFilePath;
                    pPropBag.Write(key, ref value);

                    // Write external build properies of build file to the properties
                    int propertyCounter = 0;
                    foreach (ExternalBuildProperty property in buildFile.ExternalBuildProperties) {
                        // Write value to the properties
                        string propertyKey = key + Strings.SettingsExternalBuildPropertyKey + propertyCounter;
                        object propertyValue = property.Name + ";" + property.Value;
                        pPropBag.Write(propertyKey, ref propertyValue);

                        propertyCounter++;
                    }

                    counter++;
                }

                // Write external build properties to the solution properties
                counter = 0;
                foreach (ExternalBuildProperty property in _runtime.Solution.Project.ExternalBuildProperties) {
                    // Write value to the properties
                    string key = Strings.SettingsExternalBuildPropertyKey + counter;
                    object value = property.Name + ";" + property.Value;
                    pPropBag.Write(key, ref value);

                    counter++;
                }
            }

            // Reset changed status
            _projectHasChanged = false;

            return VSConstants.S_OK;
        }

        /// <summary>
        /// Loads the user options.
        /// </summary>
        /// <param name="pPersistence">The p persistence.</param>
        /// <param name="grfLoadOpts">The GRF load opts.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.LoadUserOptions(IVsSolutionPersistence pPersistence, uint grfLoadOpts) {
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Reads the user options.
        /// </summary>
        /// <param name="pOptionsStream">The p options stream.</param>
        /// <param name="pszKey">The PSZ key.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.ReadUserOptions(IStream pOptionsStream, string pszKey) {
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Saves the user options.
        /// </summary>
        /// <param name="pPersistence">The p persistence.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.SaveUserOptions(IVsSolutionPersistence pPersistence) {
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Writes the user options.
        /// </summary>
        /// <param name="pOptionsStream">The p options stream.</param>
        /// <param name="pszKey">The PSZ key.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.WriteUserOptions(IStream pOptionsStream, string pszKey) {
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Called when [project load failure].
        /// </summary>
        /// <param name="pStubHierarchy">The p stub hierarchy.</param>
        /// <param name="pszProjectName">Name of the PSZ project.</param>
        /// <param name="pszProjectMk">The PSZ project mk.</param>
        /// <param name="pszKey">The PSZ key.</param>
        /// <returns></returns>
        int IVsPersistSolutionProps.OnProjectLoadFailure(IVsHierarchy pStubHierarchy, string pszProjectName, string pszProjectMk, string pszKey) {
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Ids the BMP splash.
        /// </summary>
        /// <param name="pIdBmp">The p id BMP.</param>
        /// <returns></returns>
        int IVsInstalledProduct.IdBmpSplash(out uint pIdBmp) {
            pIdBmp = Ressources.ApplicationBitmap;
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Ids the ico logo for aboutbox.
        /// </summary>
        /// <param name="pIdIco">The p id ico.</param>
        /// <returns></returns>
        int IVsInstalledProduct.IdIcoLogoForAboutbox(out uint pIdIco) {
            pIdIco = Ressources.ApplicationIcon;
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Officials the name.
        /// </summary>
        /// <param name="pbstrName">Name of the PBSTR.</param>
        /// <returns></returns>
        int IVsInstalledProduct.OfficialName(out string pbstrName) {
            pbstrName = Strings.ApplicationName;
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Products the details.
        /// </summary>
        /// <param name="pbstrProductDetails">The PBSTR product details.</param>
        /// <returns></returns>
        int IVsInstalledProduct.ProductDetails(out string pbstrProductDetails) {
            pbstrProductDetails = Strings.ApplicationDescription;
            return VSConstants.S_OK;
        }

        /// <summary>
        /// Products the ID.
        /// </summary>
        /// <param name="pbstrPID">The PBSTR PID.</param>
        /// <returns></returns>
        int IVsInstalledProduct.ProductID(out string pbstrPID) {
            pbstrPID = Strings.VersionNumber;
            return VSConstants.S_OK;
        }
    }
}
